package cn.xuewei.service;

import cn.xuewei.mapper.MessageMapper;
import cn.xuewei.mapper.SessionListMapper;
import cn.xuewei.mapper.UserMapper;
import cn.xuewei.pojo.entity.Message;
import cn.xuewei.pojo.entity.SessionList;
import cn.xuewei.pojo.vo.UserChatVO;
import cn.xuewei.utils.CurPool;
import cn.xuewei.utils.JsonUtils;
import cn.xuewei.utils.SpringContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
@ServerEndpoint("/websocket/{userId}/{sessionId}")
//每一个用户都有一个该对象
//此注解相当于设置访问URL
public class WebSocket {

    @Autowired
    private SessionListMapper sessionListMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MessageMapper messageMapper;

    private Session session;


    //private Httpsession httpsession;
    //声明一个httpsession对象,我们之前httpsession中存储了用户名
    @OnOpen
    public void onOpen(Session session , @PathParam(value = "userId") Integer userId,@PathParam(value = "sessionId") Integer sessionId){
        this.session = session;
        CurPool.webSockets.put(userId,this);
        List<Object> list = new ArrayList<>();
        list.add(sessionId);
        list.add(session);
        CurPool.sessionPool.put(userId,list);
        System.out.println("【websocket消息】有新的连接，总数为:"+CurPool.webSockets.size());
    }

    @OnClose
    public void onClose(){
        //断开连接删除用户删除session
        Integer userId = Integer.parseInt(this.session.getRequestParameterMap().get("userId").get(0));
        CurPool.sessionPool.remove(userId);
        CurPool.webSockets.remove(userId);
        if (userMapper == null){
            this.userMapper = (UserMapper) SpringContextUtil.getBean("userMapper");
        }
        UserChatVO userChatVO = userMapper.selectChatVoByPrimaryKey(userId);
        CurPool.curUserPool.remove(userChatVO.getUserName());
        System.out.println("【websocket消息】连接断开，总数为:"+CurPool.webSockets.size());
    }

    @OnMessage
    public void onMessage(String message){
        String sessionId = this.session.getRequestParameterMap().get("sessionId").get(0);
        if (sessionId == null){
            System.out.println("sessionId 错误");
        }
        // 在这里无法注入Mapper所以使用这种方式注入Mapper
        if (sessionListMapper == null){
            this.sessionListMapper = (SessionListMapper) SpringContextUtil.getBean("sessionListMapper");
        }
        if (userMapper == null){
            this.userMapper = (UserMapper)SpringContextUtil.getBean("userMapper");
        }
        if (messageMapper == null){
            this.messageMapper = (MessageMapper) SpringContextUtil.getBean("messageMapper");
        }

        SessionList sessionList = sessionListMapper.selectByPrimaryKey(Integer.parseInt(sessionId));

        Message messageInfo = new Message();

        messageInfo.setContent(message);
        messageInfo.setCreated(new Date());

        messageInfo.setFromUserId(sessionList.getUserId());
        messageInfo.setFromUserName(sessionList.getUserName());
        messageInfo.setFromUserImgUrl(sessionList.getUserImgUrl());

        messageInfo.setToUserId(sessionList.getToUserId());
        messageInfo.setToUserName(sessionList.getToUserName());
        messageInfo.setToUserImgUrl(sessionList.getToUserImgUrl());

        messageInfo.setUnReadFlag(0);

        //消息持久化
        messageMapper.insert(messageInfo);

        // 判断用户是否存在，不存在就结束
        List<Object> list = CurPool.sessionPool.get(sessionList.getToUserId());
        if (list == null || list.isEmpty()){
            // 用户不存在，更新未读数
            sessionListMapper.addUnReadCount(sessionList.getToUserId(),sessionList.getUserId());
        }else {
            // 用户存在，判断会话是否存在
            String id = sessionListMapper.selectByUser(sessionList.getToUserId(), sessionList.getUserId()) + "";
            String o = list.get(0) + "";
            if (id.equals(o)) {
                // 会话存在直接发送消息
                sendTextMessage(sessionList.getToUserId(), JsonUtils.objectToJson(messageInfo));
            }else {
                // 判断会话列表是否存在
                if (id == null || "".equals(id) || "null".equals(id)){
                    // 新增会话列表
                    SessionList tmpSessionList = new SessionList();

                    UserChatVO toUser = userMapper.selectChatVoByPrimaryKey(sessionList.getToUserId());
                    tmpSessionList.setUserId(toUser.getId());
                    tmpSessionList.setUserName(toUser.getUserName());
                    if(toUser.getImgUrl()==null)
                        toUser.setImgUrl("/imgs/icon.jpg");
                    tmpSessionList.setUserImgUrl(toUser.getImgUrl());

                    UserChatVO user = userMapper.selectChatVoByPrimaryKey(sessionList.getUserId());
                    tmpSessionList.setToUserId(user.getId());
                    tmpSessionList.setToUserName(user.getUserName());
                    if(user.getImgUrl()==null)
                        user.setImgUrl("/imgs/icon.jpg");
                    tmpSessionList.setToUserImgUrl(user.getImgUrl());

                    tmpSessionList.setUnReadCount(1);
                    sessionListMapper.insert(tmpSessionList);
                }else {
                    // 更新未读消息数量
                    sessionListMapper.addUnReadCount(sessionList.getToUserId(),sessionList.getUserId());
                }
                // 会话不存在发送列表消息
                List<SessionList> sessionLists = sessionListMapper.selectByUserId(sessionList.getToUserId());
                sendTextMessage(sessionList.getToUserId() , JsonUtils.objectToJson(sessionLists));
            }
        }
        System.out.println("【websocket消息】收到客户端消息:"+message);
    }

    @OnError
    public void onError(Session session,Throwable t){
        System.out.println("【websocket错误】");
        t.printStackTrace();
    }


    public void sendTextMessage(Integer userId, String message) {
        Session session = (Session)CurPool.sessionPool.get(userId).get(1);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
